package com.region.loadbalancer.group;

import java.util.concurrent.atomic.AtomicLong;

/**
 * Service base meta information
 *
 * @author liujieyu
 * @date 2023/5/24 23:41
 * @desciption
 */
public class Server {

    /**
     * server status
     */
    private ServerState status = ServerState.UP;

    /**
     * Domain Name or ip of server, e.g. 127.0.0.1 or www.baidu.com
     */
    private String host;

    /**
     * TCP / UDP port of server
     */
    private int port;

    /**
     * The protocol of server, e.g. http or https
     */
    private String protocol;

    /**
     * Detection of main pathways
     */
    private String primePath;

    /**
     * Number of times the current service has been used
     */
    private final AtomicLong count = new AtomicLong(0);

    /**
     * Average service response time
     */
    private double avgTime = 0f;

    private Server(String host, int port, String protocol, String primePath) {
        this.host = host;
        this.port = port;
        this.protocol = protocol;
        this.primePath = primePath;
    }

    public ServerState getStatus() {
        return status;
    }

    public void setStatus(ServerState status) {
        this.status = status;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public String getPrimePath() {
        return primePath;
    }

    public void setPrimePath(String primePath) {
        this.primePath = primePath;
    }

    public AtomicLong getCount() {
        return count;
    }

    public double getAvgTime() {
        return avgTime;
    }

    public void setAvgTime(double avgTime) {
        this.avgTime = avgTime;
    }

    public static ServerBuilder builder() {
        return new ServerBuilder();
    }

    /**
     * Get the service socket information
     *
     * @return
     */
    public String getSocketInfo() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(host);
        stringBuilder.append(":");
        stringBuilder.append(port);
        return stringBuilder.toString();
    }

    /**
     * Get all information about the service node
     *
     * @return
     */
    public String getServerAllInfo() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(protocol);
        stringBuilder.append("://");
        stringBuilder.append(host);
        stringBuilder.append(":");
        stringBuilder.append(port);
        stringBuilder.append(primePath);
        return stringBuilder.toString();
    }

    @Override
    public String toString() {
        StringBuilder string = new StringBuilder();
        string.append("Server {status=");
        string.append(status);
        string.append(", host=");
        string.append(host);
        string.append(", port=");
        string.append(port);
        string.append(", protocol=");
        string.append(protocol);
        string.append(", primePath=");
        string.append(primePath);
        string.append(", avgTime=");
        string.append(avgTime);
        string.append(", count=");
        string.append(count);
        string.append("}");
        return string.toString();
    }

    public static final class ServerBuilder {

        private String host;

        private int port;

        private String protocol;

        /**
         * The default detection path is /
         */
        private String primePath = "/";

        private ServerBuilder() {

        }

        public ServerBuilder host(String host) {
            this.host = host;
            return this;
        }

        public ServerBuilder port(int port) {
            this.port = port;
            return this;
        }

        public ServerBuilder protocol(String protocol) {
            this.protocol = protocol;
            return this;
        }

        public ServerBuilder primePath(String primePath) {
            if (primePath == null || "".equals(primePath)) {
                return this;
            }
            if (!primePath.startsWith("/")) {
                primePath = "/" + primePath;
            }
            this.primePath = primePath;
            return this;
        }

        public Server build() {
            return new Server(host, port, protocol, primePath);
        }
    }
}
